<?php

/**
 * SimplifyPHP Framework
 *
 * This file is part of SimplifyPHP Framework.
 *
 * SimplifyPHP Framework is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or
 * (at your option) any later version.
 *
 * SimplifyPHP Framework is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 *
 * @author Rodrigo Rutkoski Rodrigues, <rutkoski@gmail.com>
 */

/**
 * Default response manager.
 * 
 * @author Rodrigo Rutkoski Rodrigues <rutkoski@gmail.com>
 * @package Simplify_Kernel
 */
class ResponseImpl extends Dictionary implements IResponse, IRenderable
{

  /**
   * Cache output.
   * 
   * @var boolean
   */
  protected $_cacheOutput = true;

  /**
   * The layout.
   * 
   * @var mixed
   */
  protected $layout = false;

  /**
   * Response output.
   * 
   * @var string
   */
  protected $_output;

  /**
   * The template.
   * 
   * @var string
   */
  protected $template;

  /**
   * The View.
   * 
   * @var IView
   */
  protected $view;
  
  /**
   * 
   * @var array
   */
  protected $headers = array();

  public function __construct() {}

  public function initialize() {}

  /**
   * (non-PHPdoc)
   * @see simplify/kernel/IResponse#cacheOutput($cache)
   */
  public function cacheOutput($cache = null)
  {
    if (is_bool($cache))
      $this->_cacheOutput = $cache;
    return $this->_cacheOutput;
  }

  /**
   * (non-PHPdoc)
   * @see simplify/kernel/IResponse#header($string, $replace, $http_response_code)
   */
  public function header($string, $replace = null, $http_response_code = null)
  {
    /*if (!headers_sent()) {
      header($string, $replace, $http_response_code);
    }*/
    if ($replace) {
      $this->headers = array();
    }
    
    $this->headers[] = array($string, $http_response_code);
  }

  /**
   * (non-PHPdoc)
   * @see simplify/kernel/IResponse#render($output)
   */
  public function render($output = true)
  {
    $this->_output = null;
    
    if ($this->view !== false) {
      $this->_output = $this->getView()->render($this);
      
      if ($output) {
        $this->output($this->_output);
      }
    }
    
    return $this->_output;
  }

  /**
   * (non-PHPdoc)
   * @see simplify/kernel/IResponse#output($content)
   */
  public function output($content)
  {
    foreach($this->headers as $header) {
      header($header[0], false, $header[1]);
    }

    echo $content;

    return $content;
  }

  /**
   * Set the View.
   * 
   * @param IView $view view instance
   * @return void
   */
  public function setView($view)
  {
    $this->view = $view;
  }

  /**
   * Get the View.
   * 
   * @param string $engine view engine name
   * @return IView
   */
  public function getView($type = null)
  {
    if (empty($this->view)) {
      if (is_null($type)) {
        switch (true) {
        case Simplify::getRequest()->isJSON():
          $type = 'JSON';
        break;
        
        case Simplify::getRequest()->isXML():
          $type = 'XML';
        break;
        
        default:
          $type = 'PHP';
        }
      }
      
      $this->view = View::factory($type);
    }
    
    return $this->view;
  }

  /**
   * (non-PHPdoc)
   * @see simplify/kernel/IRenderable#getLayout()
   */
  public function getLayout()
  {
    if ($this->layout === false) {
      return false;
    }
    
    elseif (empty($this->layout)) {
      $layout = Simplify::getConfig()->get('{env}:home_dir') . '/layouts/default.php';
    }
    
    elseif (sy_path_is_absolute($this->layout)) {
      $layout = $this->layout;
    }
    
    else {
      $layout = Simplify::getConfig()->get('{env}:home_dir') . '/layouts/' . $this->layout . '.php';
    }
    
    if (! is_readable($layout)) {
      throw new NotFoundException(sprintf('Layout file not found: <b>%s</b>', $layout));
    }
    
    return $layout;
  }

  /**
   * (non-PHPdoc)
   * @see simplify/kernel/IRenderable#getTemplate()
   */
  public function getTemplate()
  {
    if ($this->template === false) {
      return false;
    }
    
    if (empty($this->template)) {
      throw new NotFoundException('Template file not set');
    }
    
    elseif (sy_path_is_absolute($this->template)) {
      $template = $this->template;
    }
    
    else {
      $template = Simplify::getConfig()->get('{env}:home_dir') . '/' . $this->template . '_view.php';
    }
    
    if (! is_readable($template))
      throw new NotFoundException(sprintf('Template file not found: <b>%s</b>', $template));
    
    return $template;
  }

  /**
   * (non-PHPdoc)
   * @see simplify/kernel/IRenderable#setTemplate($template)
   */
  public function setTemplate($template)
  {
    $this->template = $template;
  }

  /**
   * (non-PHPdoc)
   * @see simplify/kernel/IRenderable#setLayout($layout)
   */
  public function setLayout($layout)
  {
    $this->layout = $layout;
  }

  /**
   * URL redirection if condition is met.
   * 
   * @param boolean $condition conditional expression
   * @param string $url the url
   * @param string $http_response_code http response code
   * @return void
   */
  public function redirectIf($condition, $url, $http_response_code = null)
  {
    if ($condition)
      $this->redirect($url, $http_response_code);
  }

  /**
   * URL redirection.
   * 
   * @param string $url the url
   * @param string $http_response_code http response code
   * @return void
   */
  public function redirect($url, $http_response_code = null)
  {
    if (! sy_url_is_absolute($url))
      $url = $this->makeUrl($url);
    $this->header("Location: $url", false, $http_response_code);
    $this->output('');
    die();
  }

  /**
   * Make a simplify URL from a route.
   * 
   * @param string $route the route
   * @param string $baseUrl base url
   * @return string the URL
   */
  public function makeUrl($route)
  {
    if (sy_url_is_absolute($route)) return $route;
    
    $args = func_get_args();
    
    $route = implode('/', $args);
    $route = preg_replace(array(
      '#\/+#', '#(^\/+|\/+$)#' 
    ), array(
      '/', '' 
    ), $route);
    
    if (! empty($route))
      $route = '/' . $route;
    
    $url = Simplify::getConfig()->get('app_url');
    if (Simplify::getConfig()->get('disable_mod_rewrite') == true) {
      $url .= '/index.php';
    }
    $url .= $route;
    
    return $url;
  }

}

?>